package com.cxd.app.service;

import java.util.HashMap;
import java.util.List;
import java.util.Map;

import javax.annotation.Resource;

import org.springframework.dao.DuplicateKeyException;
import org.springframework.stereotype.Service;

import com.cxd.app.mapper.read.RFeeConfigMapper;
import com.cxd.base.common.constants.FeeConfigConstants.OperateMode;
import com.cxd.base.common.exception.CxdException;
import com.cxd.base.util.ArithUtil;
import com.google.common.primitives.Doubles;

/**
 * <一句话功能简述> <功能详细描述>
 * @author wtj
 * @date 2015年12月11日 上午11:06:58
 * @company CXD
 * @version [Copyright (c) 2015 V001]
 */
@Service("feeConfigService")
public class FeeConfigService {
	@Resource
	public RFeeConfigMapper rfeeConfigMapper;
	/**
	 * key：节点、费用类型、影响因子、影响因子值、是否为区间 如果不是区间，则上述key为联合主键； 如果是区间，则key+区间上限下限为联合主键
	 * 
	 * @param feePoint
	 *            费用节点
	 * @param feeType
	 *            费用类型
	 * @param factor
	 *            影响因子
	 * @param factorValue
	 *            影响因子的值
	 * @param value
	 *            返回该值的费用
	 * @return
	 * @since 2.0
	 */
	public double getFee(String feePoint, String feeType, String factor,
			String factorValue, double value) {
		
		Map<String,Object> root = new HashMap<String,Object>();
			root.put("feePoint", feePoint);
			root.put("feeType", feeType);
			root.put("factor", factor);
			root.put("factorValue", factorValue);
			root.put("value", value);
		List<Map<String,Object>> fcs = rfeeConfigMapper.loadFeeConfigurationBase(root);
		if (fcs.size() > 1) {
			// 找到多个，抛异常。
			throw new DuplicateKeyException("feePoint:" + feePoint
					+ " feeType:" + feeType + " factor:" + factor
					+ " factorValue:" + factorValue + " value:" + value
					+ "  duplication!");
		}
		if (fcs.size() == 0) {
			throw new CxdException("feePoint:"
					+ feePoint + " feeType:" + feeType + " factor:" + factor
					+ " factorValue:" + factorValue + " value:" + value
					+ "  not found!");
		}
		Map<String,Object> fc = fcs.get(0);
		if (fc.get("OPERATE_MODE").equals(OperateMode.FIXED)) {
			return Double.parseDouble(fc.get("FEE").toString());
		} else if (fc.get("OPERATE_MODE").equals(OperateMode.RATE)) {
			double fee = ArithUtil.round(ArithUtil.mul(value, Double.parseDouble(fc.get("FEE").toString())), 2);
			return Doubles.min(fee,fc.get("FEE_UPPER_LIMIT") == null ? fee : (Double)fc.get("FEE_UPPER_LIMIT"));
		} else {
			throw new RuntimeException("operateMode: " + fc.get("OPERATE_MODE")	+ "not found!");
		}
	}
}
